private {
	import quaternion;
	import derelict.opengl.gl;
	import derelict.sdl.sdl;
	import std.stdio;
}

private const float speed	=	10.f;
private const float aspeed	=	0.01;

struct Position{
	float x	=	14;
	float y	=	0;
	float z	=	10;
}

struct keyDownFunc{
	bool down	=	false;
	void delegate()	fnc	=	null;
}

public class Camera {
	Quaternion quat;
	Position position;
	float verAngle = .0f;
	float horAngle = .0f;
	float eye	=	1.f;
	float vec[3];
	float matrix[16];
	Quaternion q,ver,hor;
	keyDownFunc keys[400];

	this(){
		quat = new Quaternion();
		initKeyDownFunc();
	}

	void genVec(){
		hor.createMatrix(matrix);
		vec[1] = matrix[9] / speed;

		q = ver.multiply(hor);
		q.createMatrix(matrix);
		vec[0] = matrix[8] / speed;
		vec[2] = matrix[10] / speed;
	}

	void checkDown(){
		for(int i=0;i<keys.length;i++)
			if(keys[i].down==true)
				keys[i].fnc();
	}

	public void set(){
		q=new Quaternion;
		ver = new Quaternion(.0f, 1.f, .0f, horAngle);
		hor = new Quaternion(1.f,.0f,.0f,verAngle);
		eye = 1.f;
		checkDown();
		q = hor.multiply(ver);
		q.createMatrix(matrix);
		glLoadIdentity();
		glMultMatrixf(matrix);

		glTranslatef(-position.x,-position.y-eye,-position.z);
	}

	void foo(){}

	void initKeyDownFunc(){
		for(int i=0; i < keys.length; i++)
			keys[i].fnc = &foo;
		keys[SDLK_w].fnc	=	&goForward;
		keys[SDLK_s].fnc	=	&goBackward;
		keys[SDLK_a].fnc	=	&strafeLeft;
		keys[SDLK_d].fnc	=	&strafeRight;
		keys[SDLK_c].fnc	=	&crouch;
	}

	Position getPosition(){
		return position;
	}

	void keyUp(int k){
		if( k < keys.length)
			keys[k].down = false;
	}

	void keyDown(int k){
		if( k < keys.length)
			keys[k].down = true;
	}

	void goForward(){
		genVec();
		position.x+=vec[0];
//		position.y+=vec[1];
		position.z-=vec[2];
	}

	void goBackward(){
		genVec();
		position.x-=vec[0];
//		position.y-=vec[1];
		position.z+=vec[2];
	}

	void turnLeft(){
		horAngle-=aspeed;
	}

	void turnRight(){
		horAngle+=aspeed;
	}

	void strafeLeft(){
		genVec();
		position.x -= vec[2];
		position.z -= vec[0];
	}

	void strafeRight(){
		genVec();
		position.x += vec[2];
		position.z += vec[0];
	}

	void crouch(){
		eye = .5f;
	}

	void mouseMotion(int dx, int dy){
		horAngle += dx/400.f;
		verAngle += dy/300.f;
	}


	~this(){
	}
}
